package com.paw.ruoyi.admin.core.intercepter;

import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.paw.ruoyi.admin.common.constant.CommonConstant;
import com.paw.ruoyi.admin.common.constant.RedisPrefixKeyConstant;
import com.paw.ruoyi.admin.common.context.UserContext;
import com.paw.ruoyi.admin.common.context.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Rubble
 * @date 2021/8/27
 **/
@Slf4j
public class UserInfoInterceptor implements HandlerInterceptor {

  private StringRedisTemplate stringRedisTemplate;

  public UserInfoInterceptor (StringRedisTemplate stringRedisTemplate) {
    this.stringRedisTemplate = stringRedisTemplate;
  }

  @Override
  public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    String userInfoEncode = request.getHeader(CommonConstant.HEADER_USER_INFO);
    log.debug("UserInfoInterceptor userInfoEncode: {}",userInfoEncode);
    if(StrUtil.isNotEmpty(userInfoEncode) && isBase64(userInfoEncode)){
      try {
        String userInfoStr = Base64.decodeStr(userInfoEncode);
        log.debug("UserInfoInterceptor userInfoStr: {}",userInfoStr);
        UserContext userContext = JSON.parseObject(userInfoStr, UserContext.class);
        UserContextHolder.setUser(userContext);
      }catch (Exception e){
        log.error("UserInfoInterceptor userInfoStr interceptor error",e);
      }
    }
    if(UserContextHolder.getUserId()==null){
      String token = request.getHeader(CommonConstant.TOKEN);
      if(StrUtil.isEmpty(token)){
        token = request.getParameter(CommonConstant.TOKEN);
      }
      if(StrUtil.isNotEmpty(token)){
        String tokenKey = RedisPrefixKeyConstant.getKey(RedisPrefixKeyConstant.PRE_TOKEN,token);
        String userInfoStr = stringRedisTemplate.opsForValue().get(tokenKey);
        if(StrUtil.isNotEmpty(userInfoStr)){
          UserContext userContext = JSON.parseObject(userInfoStr, UserContext.class);
          UserContextHolder.setUser(userContext);
        }
      }
    }

    return true;
  }


  @Override
  public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

  }

  @Override
  public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    UserContextHolder.remove();
  }

  private static boolean isBase64(String str) {
    String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
    return Pattern.matches(base64Pattern, str);
  }

}
